/*
 
 */
package com.jme3.gde.gui.extra.xam.model.visitor;

import com.jme3.gde.gui.extra.xam.model.AttributesType;
import com.jme3.gde.gui.extra.xam.model.ControlDefinition;
import com.jme3.gde.gui.extra.xam.model.ControlType;
import com.jme3.gde.gui.extra.xam.model.EffectValueType;
import com.jme3.gde.gui.extra.xam.model.EffectsType;
import com.jme3.gde.gui.extra.xam.model.ElementType;
import com.jme3.gde.gui.extra.xam.model.ImageType;
import com.jme3.gde.gui.extra.xam.model.InteractType;
import com.jme3.gde.gui.extra.xam.model.LayerType;
import com.jme3.gde.gui.extra.xam.model.NiftyComponent;
import com.jme3.gde.gui.extra.xam.model.NiftyExtensibilityElement;
import com.jme3.gde.gui.extra.xam.model.NiftyType;
import com.jme3.gde.gui.extra.xam.model.OnHoverType;
import com.jme3.gde.gui.extra.xam.model.PanelType;
import com.jme3.gde.gui.extra.xam.model.PopupType;
import com.jme3.gde.gui.extra.xam.model.RegisterEffectType;
import com.jme3.gde.gui.extra.xam.model.RegisterMouseCursorType;
import com.jme3.gde.gui.extra.xam.model.RegisterMusicType;
import com.jme3.gde.gui.extra.xam.model.RegisterSoundType;
import com.jme3.gde.gui.extra.xam.model.ResourceBundleType;
import com.jme3.gde.gui.extra.xam.model.ScreenType;
import com.jme3.gde.gui.extra.xam.model.SingleEffectType;
import com.jme3.gde.gui.extra.xam.model.SingleEffectTypeBase;
import com.jme3.gde.gui.extra.xam.model.SingleEffectTypeHover;
import com.jme3.gde.gui.extra.xam.model.SingleEffectTypeOnHover;
import com.jme3.gde.gui.extra.xam.model.StyleType;
import com.jme3.gde.gui.extra.xam.model.TextType;
import com.jme3.gde.gui.extra.xam.model.UseControlsType;
import com.jme3.gde.gui.extra.xam.model.UseStylesType;
import org.netbeans.modules.xml.xam.AbstractComponent;
import org.netbeans.modules.xml.xam.ComponentUpdater;
import org.netbeans.modules.xml.xam.dom.DocumentComponent;

/**
 * Visitor to add or remove a child of a domain component.
 * 
 * @author cuongnguyen
 */
// Generated by XAM AutoGen Tool v0.2
public class ChildComponentUpdateVisitor<T extends NiftyComponent>
        extends DefaultVisitor
        implements ComponentUpdater<T> {
    
    private org.netbeans.modules.xml.xam.ComponentUpdater.Operation operation;
    private NiftyComponent parent;
    private int index;
    private boolean canAdd = false;
    
    /**
     * Creates a new instance of ChildComponentUpdateVisitor
     */
    public ChildComponentUpdateVisitor() {
    }
    
    public boolean canAdd(NiftyComponent target, org.netbeans.modules.xml.xam.Component child) {
        if (!(child instanceof NiftyComponent)) return false;
        update(target, (NiftyComponent) child, null);
        return canAdd;
    }
    
    public void update(NiftyComponent target, NiftyComponent child, Operation operation) {
        update(target, child, -1, operation);
    }
    
    public void update(NiftyComponent target, NiftyComponent child, int index, Operation operation) {
        assert target != null;
        assert child != null;

        this.parent = target;
        this.operation = operation;
        this.index = index;
        child.accept(this);
    }
    
    private void addChild(String eventName, DocumentComponent child) {
        ((AbstractComponent) parent).insertAtIndex(eventName, child, index);
    }
    
    private void removeChild(String eventName, DocumentComponent child) {
        ((AbstractComponent) parent).removeChild(eventName, child);
    }

    @Override
    public void visit(ElementType child) {
        if (parent instanceof ControlDefinition) {
            if (operation == Operation.ADD) {
                addChild(ControlDefinition.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(ControlDefinition.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        if (parent instanceof PanelType) {
            if (operation == Operation.ADD) {
                addChild(PanelType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(PanelType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        if (parent instanceof PopupType) {
            if (operation == Operation.ADD) {
                addChild(PopupType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(PopupType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(LayerType child) {
        if (parent instanceof ScreenType) {
            if (operation == Operation.ADD) {
                addChild(ScreenType.LAYERTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(ScreenType.LAYERTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(PanelType child) {
        if (parent instanceof LayerType) {
            if (operation == Operation.ADD) {
                addChild(LayerType.PANELTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(LayerType.PANELTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(ImageType child) {
        if (parent instanceof ControlDefinition) {
            if (operation == Operation.ADD) {
                addChild(ControlDefinition.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(ControlDefinition.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        if (parent instanceof PanelType) {
            if (operation == Operation.ADD) {
                addChild(PanelType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(PanelType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        if (parent instanceof PopupType) {
            if (operation == Operation.ADD) {
                addChild(PopupType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(PopupType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(TextType child) {
        if (parent instanceof ControlDefinition) {
            if (operation == Operation.ADD) {
                addChild(ControlDefinition.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(ControlDefinition.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        if (parent instanceof PanelType) {
            if (operation == Operation.ADD) {
                addChild(PanelType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(PanelType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        if (parent instanceof PopupType) {
            if (operation == Operation.ADD) {
                addChild(PopupType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(PopupType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(ControlDefinition child) {
        if (parent instanceof NiftyType) {
            if (operation == Operation.ADD) {
                addChild(NiftyType.CONTROLDEFINITION_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(NiftyType.CONTROLDEFINITION_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(ControlType child) {
        if (parent instanceof ControlDefinition) {
            if (operation == Operation.ADD) {
                addChild(ControlDefinition.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(ControlDefinition.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        if (parent instanceof PanelType) {
            if (operation == Operation.ADD) {
                addChild(PanelType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(PanelType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        if (parent instanceof PopupType) {
            if (operation == Operation.ADD) {
                addChild(PopupType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(PopupType.ELEMENTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(UseStylesType child) {
        if (parent instanceof NiftyType) {
            if (operation == Operation.ADD) {
                addChild(NiftyType.USESTYLESTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(NiftyType.USESTYLESTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(UseControlsType child) {
        if (parent instanceof NiftyType) {
            if (operation == Operation.ADD) {
                addChild(NiftyType.USECONTROLSTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(NiftyType.USECONTROLSTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(RegisterSoundType child) {
        if (parent instanceof NiftyType) {
            if (operation == Operation.ADD) {
                addChild(NiftyType.REGISTERSOUNDTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(NiftyType.REGISTERSOUNDTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(RegisterEffectType child) {
        if (parent instanceof NiftyType) {
            if (operation == Operation.ADD) {
                addChild(NiftyType.REGISTEREFFECTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(NiftyType.REGISTEREFFECTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(RegisterMusicType child) {
        if (parent instanceof NiftyType) {
            if (operation == Operation.ADD) {
                addChild(NiftyType.REGISTERMUSICTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(NiftyType.REGISTERMUSICTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(RegisterMouseCursorType child) {
        if (parent instanceof NiftyType) {
            if (operation == Operation.ADD) {
                addChild(NiftyType.REGISTERMOUSECURSORTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(NiftyType.REGISTERMOUSECURSORTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(ResourceBundleType child) {
        if (parent instanceof NiftyType) {
            if (operation == Operation.ADD) {
                addChild(NiftyType.RESOURCEBUNDLETYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(NiftyType.RESOURCEBUNDLETYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(AttributesType child) {
        if (parent instanceof StyleType) {
            if (operation == Operation.ADD) {
                addChild(StyleType.ATTRIBUTESTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(StyleType.ATTRIBUTESTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(InteractType child) {
        if (parent instanceof ElementType) {
            if (operation == Operation.ADD) {
                addChild(ElementType.INTERACTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(ElementType.INTERACTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        if (parent instanceof StyleType) {
            if (operation == Operation.ADD) {
                addChild(StyleType.INTERACTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(StyleType.INTERACTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(EffectValueType child) {
        if (parent instanceof SingleEffectTypeBase) {
            if (operation == Operation.ADD) {
                addChild(SingleEffectTypeBase.EFFECTVALUETYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(SingleEffectTypeBase.EFFECTVALUETYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(SingleEffectTypeBase child) {
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(SingleEffectType child) {
        if (parent instanceof EffectsType) {
            if (operation == Operation.ADD) {
                addChild(EffectsType.SINGLEEFFECTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(EffectsType.SINGLEEFFECTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(SingleEffectTypeOnHover child) {
        if (parent instanceof EffectsType) {
            if (operation == Operation.ADD) {
                addChild(EffectsType.SINGLEEFFECTTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(EffectsType.SINGLEEFFECTTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(OnHoverType child) {
        if (parent instanceof SingleEffectTypeOnHover) {
            if (operation == Operation.ADD) {
                addChild(SingleEffectTypeOnHover.ONHOVERTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(SingleEffectTypeOnHover.ONHOVERTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(SingleEffectTypeHover child) {
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(EffectsType child) {
        if (parent instanceof ElementType) {
            if (operation == Operation.ADD) {
                addChild(ElementType.EFFECTSTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(ElementType.EFFECTSTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        if (parent instanceof StyleType) {
            if (operation == Operation.ADD) {
                addChild(StyleType.EFFECTSTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(StyleType.EFFECTSTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(StyleType child) {
        if (parent instanceof NiftyType) {
            if (operation == Operation.ADD) {
                addChild(NiftyType.STYLETYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(NiftyType.STYLETYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(PopupType child) {
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(ScreenType child) {
        if (parent instanceof NiftyType) {
            if (operation == Operation.ADD) {
                addChild(NiftyType.SCREENTYPE_PROPERTY, child);
            } else if (operation == Operation.REMOVE) {
                removeChild(NiftyType.SCREENTYPE_PROPERTY, child);
            } else if (operation == null) {
                canAdd = true;
            }
            return;
        } 
        checkOperationOnUnmatchedParent();
    }

    @Override
    public void visit(NiftyType child) {
        checkOperationOnUnmatchedParent();
    }


   @Override
    public void visit(NiftyExtensibilityElement child) {
        if (parent instanceof NiftyExtensibilityElement.UpdaterProvider) {
            NiftyExtensibilityElement.UpdaterProvider target = 
                    (NiftyExtensibilityElement.UpdaterProvider) parent;
            ComponentUpdater<NiftyExtensibilityElement> updater = target.getComponentUpdater();
            if (operation != null) {
                updater.update(target, child, index, operation);
            } else {
                canAdd = false;
                if (updater instanceof ComponentUpdater.Query) {
                    canAdd = ((ComponentUpdater.Query) updater).canAdd(target, child);
                } 
            }
        } else {
            if (operation == Operation.ADD) {
                parent.addExtensibilityElement(child);
            } else if (operation == Operation.REMOVE) {
                parent.removeExtensibilityElement(child);
            } else if (operation == null) {
                canAdd = true;
                if (child instanceof NiftyExtensibilityElement.ParentSelector) {
                    canAdd = ((NiftyExtensibilityElement.ParentSelector)child).canBeAddedTo(parent);
                }
            }
        }
    }

    private void checkOperationOnUnmatchedParent() {
        if (operation != null) {
            // note this unmatch should be caught by validation, 
            // we don't want the UI view to go blank on invalid but still well-formed document
            //throw new IllegalArgumentException("Unmatched parent-child components"); //NO18N
        } else {
            canAdd = false;
        }
    }
}
